<?php
defined('BASEPATH') or exit('No direct script access allowed!');

/**
 * This class is to limit setting prop of the class.
 * To make sure you can only access the prop allowed.
 */
abstract class Limited {
  protected $props = array();
  function __set($key, $val) {
    if(!in_array($key, $props)) {
      show_error('ERROR: NOT ALLOW TO SET PROP `'.$key.'` IN SOME CLASS, PLEASE CHECK YOUR CODE!', 500);
      exit();
    }
    $this->$key = $val;
  }

  protected function __allow($arr) {
    $this->props = array_merge($this->props, $arr);
  }

  public function prop() {
    return $this->props;
  }
}

class UserData extends Limited {
  function __construct() {
    $this->__allow(array('id', 'username', 'password', 'name', 'group'));
  }
}

class ProjectData extends Limited {
  function __construct() {
    /* Identities */
    $this->__allow(array('id', 'hash'));

    /* Props */
    $this->__allow(array('name', 'summary', 'createdTime', 'createdBy', 'group'));
  }
}

class TaskSummary extends Limited{
  function __construct() {
    /* Identities */
    $this->__allow(array('id', 'hash', 'projectId', 'projectHash'));
    /* These var is used to build tree */
    $this->__allow(array('left', 'right', 'parentId', 'depth'));

    /* Props */
    $this->__allow(array('hide', 'finished', 'name', 'tagColor'));
  }
}

class TaskData extends TaskSummary {
  function __construct() {
    parent::__construct();
    /* Common props */
    $this->__allow(array('createdTime', 'createdBy', 'detail'));
  }
}

class CommentData extends Limited {
  function __construct() {
    /* Identities */
    $this->__allow(array('id', 'hash', 'taskId', 'taskHash', 'projectId', 'projectHash'));

    /* Props */
    $this->__allow(array('author', 'postTime', 'content'));
  }
}

function apply($template, $obj) {
  foreach ($obj as $key => $value) {
    $template->$key = $value;
  }
  return $template;
}
